home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Mark Pilgrim / Jotto ][ 1.2 / source / Shell ƒ / prefs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-30  |  10.8 KB  |  405 lines  |  [TEXT/MMCC]

  1. #include "program globals.h"
  2. #include "prefs.h"
  3. #include "help.h"
  4. #include "dialogs.h"
  5. #include "environment.h"
  6. #include "sounds.h"
  7. #include "util.h"
  8. #include "window layer.h"
  9. #include "Folders.h"
  10.  
  11. #define        PREFS_FILE_NAME            "\pJotto ][ prefs"
  12. #define        PREFS_TYPE                'PREF'
  13. // CREATOR is #defined in "program globals.h"
  14. #define        PREFS_HEADER_VERSION    2
  15.  
  16. Str255            gMyName;
  17. Str255            gMyOrg;
  18.  
  19. typedef struct
  20. {
  21.     char            regname[40];
  22.     char            regorg[40];
  23.     unsigned char    sound;
  24.     unsigned char    dup;
  25.     unsigned char    nonwords;
  26.     unsigned char    animation;
  27.     unsigned char    numletters;
  28.     unsigned char    unused;
  29.     short            lastwipe;
  30.     short            maintopic;
  31.     short            subtopic;
  32.     long            fileID;
  33. } PrefStruct;
  34.  
  35. /* internal globals for use in prefs.c only */
  36. static long            gFileID;
  37. static Boolean        gCanSavePrefs;
  38. static PrefStruct    thePrefs;
  39. static long            gPrefsFilePos;
  40.  
  41. /*-----------------------------------------------------------------------------------*/
  42. /* internal stuff for prefs.c                                                        */
  43.  
  44. enum PrefErrorTypes OpenPrefsFile(short *prefsFileID);
  45. enum PrefErrorTypes SetupNewPrefsFile(short prefsFileID);
  46. void ClosePrefsFile(short prefsFileID);
  47. enum PrefErrorTypes GetNextPrefs(short prefsFileID);
  48. enum PrefErrorTypes SavePrefs(short prefsFileID);
  49. enum PrefErrorTypes CheckVersion(short prefsFileID);
  50. enum PrefErrorTypes GetFileID(void);
  51. enum PrefErrorTypes CheckFileID(void);
  52. enum PrefErrorTypes Virgin(short prefsFileID);
  53. void DefaultPrefs(void);
  54. void CopyGlobalsToPrefs(void);
  55. void CopyPrefsToGlobals(void);
  56. void GetRegistration(void);
  57.  
  58. void SaveThePrefs(void)
  59. /* standard procedure callable from anywhere to save prefs to disk (if possible) */
  60. {
  61.     short            prefsFileID;
  62.     
  63.     if (gCanSavePrefs)        /* if we had no errors in PreferencesInit() */
  64.     {
  65.         OpenPrefsFile(&prefsFileID);    /* open the prefs file */
  66.         CopyGlobalsToPrefs();            /* copy global variables to prefs struct */
  67.         SavePrefs(prefsFileID);            /* save prefs to disk */
  68.         ClosePrefsFile(prefsFileID);    /* close prefs file */
  69.     }
  70. }
  71.  
  72. enum PrefErrorTypes PreferencesInit(void)
  73. {
  74.     short            prefsFileID;
  75.     enum PrefErrorTypes        err;
  76.     
  77.     gCanSavePrefs=FALSE;    /* assume the worst and maybe you'll be pleasantly surprised */
  78.     err=GetFileID();        /* get application file ID */
  79.     if (err!=prefs_allsWell)    /* screwed up already?!? */
  80.         return err;
  81.     
  82.     err=OpenPrefsFile(&prefsFileID);    /* open prefs file (or create new one) */
  83.     if (err!=prefs_allsWell)
  84.     {
  85.         if ((err==prefs_diskReadErr) || (err==prefs_diskWriteErr) || (err==prefs_virginErr))
  86.             ClosePrefsFile(prefsFileID);    /* close & abort if error or if new prefs */
  87.         return err;
  88.     }
  89.     
  90.     err=CheckVersion(prefsFileID);        /* check prefs version */
  91.     if (err!=prefs_allsWell)
  92.     {
  93.         ClosePrefsFile(prefsFileID);
  94.         return err;
  95.     }
  96.     
  97.     GetFPos(prefsFileID, &gPrefsFilePos);
  98.     gPrefsFilePos-=sizeof(thePrefs);
  99.     do
  100.     {
  101.         gPrefsFilePos+=sizeof(thePrefs);
  102.         err=GetNextPrefs(prefsFileID);        /* get prefs struct from file */
  103.         if (err==prefs_noMorePrefsErr)        /* or not */
  104.             return (Virgin(prefsFileID));    /* can't find our file ID, it's our first time */
  105.         
  106.         if (err!=prefs_allsWell)            /* any other error, just abort */
  107.         {
  108.             ClosePrefsFile(prefsFileID);
  109.             return err;
  110.         }
  111.         
  112.         err=CheckFileID();                    /* check file ID of current prefs struct */
  113.     }
  114.     while (err==prefs_IDNotMatchErr);
  115.     
  116.     CopyPrefsToGlobals();                    /* copy prefs struct to program globals */
  117.     ClosePrefsFile(prefsFileID);            /* close prefs file */
  118.     
  119.     return prefs_allsWell;                    /* piece o' cake */
  120. }
  121.  
  122. void PrefsError(enum PrefErrorTypes err)
  123. {
  124.     Str255            tempStr;
  125.     
  126.     switch (err)
  127.     {
  128.         case prefs_diskReadErr:
  129.         case prefs_diskWriteErr:
  130.         case prefs_cantCreatePrefsErr:
  131.         case prefs_cantOpenPrefsErr:
  132.         case prefs_versionNotSupportedErr:
  133.             DefaultPrefs();                    /* use default prefs if error */
  134.             gCanSavePrefs=FALSE;            /* don't bother trying to save prefs later */
  135.             GetIndString(tempStr, 128, err);    /* get error string from .rsrc file */
  136.             ParamText(tempStr, "\p", "\p", "\p");
  137.             PositionDialog('ALRT', largeAlert);
  138.             StopAlert(largeAlert, 0L);        /* display error alert */
  139.             break;
  140.         default:
  141.             gCanSavePrefs=TRUE;                /* can save prefs to disk later if needed */
  142.             break;
  143.     }
  144. }
  145.  
  146. enum PrefErrorTypes OpenPrefsFile(short *prefsFileID)
  147. {
  148.     short            thisFile;
  149.     Boolean            newPrefs;
  150.     unsigned char    *name=PREFS_FILE_NAME;
  151.     OSErr            isHuman;
  152.     short            vRefNum;
  153.     long            dirID;
  154.     FSSpec            prefsFile;
  155.     
  156.     newPrefs=FALSE;
  157.     /* find vRefNum and dirID of preferences folder, creating it if necessary */
  158.     isHuman=FindFolder(kOnSystemDisk, 'pref', kCreateFolder, &vRefNum, &dirID);
  159.     
  160.     if (isHuman!=noErr)        /* screwed up already?!? */
  161.         return prefs_cantOpenPrefsErr;
  162.     
  163.     isHuman=FSMakeFSSpec(vRefNum, dirID, name, &prefsFile);    /* make FSSpec out of it */
  164.     if (isHuman!=noErr)
  165.     {
  166.         if (isHuman==fnfErr)    /* FSSpec is valid, but prefs file does not exist */
  167.         {
  168.             isHuman=FSpCreate(&prefsFile, CREATOR, PREFS_TYPE, 0);    /* so create it */
  169.             if (isHuman!=noErr)                                        /* or not */
  170.                 return prefs_cantCreatePrefsErr;
  171.             newPrefs=TRUE;        /* signal that prefs file is new */
  172.         }
  173.         else return prefs_cantOpenPrefsErr;
  174.     }
  175.     isHuman=FSpOpenDF(&prefsFile, fsRdWrPerm, &thisFile);    /* open prefs file */
  176.     *prefsFileID=thisFile;        /* store file reference number */
  177.     if (isHuman!=noErr)
  178.         return prefs_cantOpenPrefsErr;
  179.     
  180.     if (newPrefs)
  181.         return SetupNewPrefsFile(*prefsFileID);        /* needs initial setup if new */
  182.     
  183.     return prefs_allsWell;
  184. }
  185.  
  186. enum PrefErrorTypes SetupNewPrefsFile(short prefsFileID)
  187. /* this writes the prefs version number to the newly created prefs file, so we can
  188.    tell if the prefs file was created by a later version of the program and is
  189.    therefore in a format that we don't support -- forward compatability!  what
  190.    a concept! */
  191. {
  192.     long            count;
  193.     short            temp;
  194.     
  195.     gPrefsFilePos=2L;
  196.     if (SetEOF(prefsFileID, 2L)!=noErr)    /* set length of prefs file to 2 */
  197.         return prefs_diskWriteErr;
  198.     
  199.     SetFPos(prefsFileID, 1, 0L);
  200.     temp=PREFS_HEADER_VERSION;            /* get the prefs version (hardcoded) */
  201.     count=2L;
  202.     if (FSWrite(prefsFileID, &count, &temp)!=noErr)        /* write prefs version */
  203.         return prefs_diskWriteErr;        
  204.     
  205.     return Virgin(prefsFileID);            /* be gentle; it's our first time */
  206. }
  207.  
  208. void ClosePrefsFile(short prefsFileID)
  209. {
  210.     FSClose(prefsFileID);                /* close file on disk */
  211.     FlushVol(0L, kOnSystemDisk);        /* flush volume to write out new info */
  212. }
  213.  
  214. enum PrefErrorTypes GetNextPrefs(short prefsFileID)
  215. {
  216.     OSErr        isHuman;
  217.     long        count;
  218.     
  219.     count=sizeof(thePrefs);
  220.     isHuman=FSRead(prefsFileID, &count, &thePrefs);        /* get next prefs struct */
  221.     if (isHuman==eofErr)    /* no more left */
  222.         return prefs_noMorePrefsErr;
  223.     if (isHuman!=noErr)        /* some other error */
  224.         return prefs_diskReadErr;
  225.     
  226.     return prefs_allsWell;
  227. }
  228.  
  229. enum PrefErrorTypes SavePrefs(short prefsFileID)
  230. {
  231.     long        oldEOF;
  232.     long        count;
  233.     
  234.     GetEOF(prefsFileID, &oldEOF);
  235.     if (gPrefsFilePos>=oldEOF)        /* add new prefs struct onto end of prefs file */
  236.     {
  237.         if (SetEOF(prefsFileID, oldEOF+sizeof(thePrefs))!=noErr)
  238.             return prefs_diskWriteErr;
  239.     }
  240.     
  241.     SetFPos(prefsFileID, 1, gPrefsFilePos);        /* set position inside prefs file */
  242.     count=sizeof(thePrefs);
  243.     /* write prefs struct and return appropriate error code */
  244.     return (FSWrite(prefsFileID, &count, &thePrefs)!=noErr) ?
  245.         prefs_diskWriteErr : prefs_allsWell;
  246. }
  247.  
  248. enum PrefErrorTypes CheckVersion(short prefsFileID)
  249. {
  250.     OSErr        isHuman;
  251.     long        count;
  252.     short            temp;
  253.     
  254.     count=2L;
  255.     isHuman=FSRead(prefsFileID, &count, &temp);        /* get prefs version */
  256.     if (isHuman!=noErr)
  257.         return prefs_diskReadErr;
  258.     if (temp>PREFS_HEADER_VERSION)                    /* too new */
  259.         return prefs_versionNotSupportedErr;
  260.     if (temp<PREFS_HEADER_VERSION)                    /* old; overwrite */
  261.         return SetupNewPrefsFile(prefsFileID);
  262.     
  263.     return prefs_allsWell;
  264. }
  265.  
  266. enum PrefErrorTypes GetFileID(void)
  267. {
  268.     ParamBlockRec    pb;
  269.     
  270.     pb.fileParam.ioCompletion=0L;
  271.     pb.fileParam.ioNamePtr=LMGetCurApName();
  272.     pb.fileParam.ioVRefNum=0;
  273.     pb.fileParam.ioFVersNum=0;
  274.     pb.fileParam.ioFDirIndex=0;
  275.     if (PBGetFInfo(&pb, FALSE)!=noErr)
  276.         return prefs_diskReadErr;
  277.     
  278.     gFileID=pb.fileParam.ioFlNum;
  279.     
  280.     return prefs_allsWell;
  281. }
  282.  
  283. enum PrefErrorTypes CheckFileID(void)
  284. {
  285.     /* compare file ID in current prefs struct to application's file ID */
  286.     return (thePrefs.fileID==gFileID) ? prefs_allsWell : prefs_IDNotMatchErr;
  287. }
  288.  
  289. enum PrefErrorTypes Virgin(short prefsFileID)
  290. {
  291.     enum PrefErrorTypes    err;
  292.     
  293.     DefaultPrefs();
  294.     CopyGlobalsToPrefs();
  295.     err=SavePrefs(prefsFileID);
  296.     if (err!=prefs_allsWell)
  297.         return err;
  298.     GetRegistration();
  299.     CopyGlobalsToPrefs();
  300.     err=SavePrefs(prefsFileID);
  301.     
  302.     return (err==prefs_allsWell) ? prefs_virginErr : err;
  303. }
  304.  
  305. void DefaultPrefs(void)
  306. {
  307.     unsigned char        *bob="\pBob";
  308.     
  309.     Mymemcpy((Ptr)gMyName, (Ptr)bob, bob[0]+1);
  310.     gMyOrg[0]=0x00;
  311.     gMainTopicShowing=gSubTopicShowing=0;
  312.     gSoundToggle=0xFF;
  313.     gAllowDup=0x00;
  314.     gNonWordsCount=0xFF;
  315.     gAnimation=0xFF;
  316.     gNumLetters=5;
  317.     gLastWipe=0;
  318. }
  319.  
  320. void CopyGlobalsToPrefs(void)
  321. {
  322.     Mymemset((Ptr)&thePrefs, 0, sizeof(thePrefs));
  323.     if (gMyName[0]>0x27)
  324.         gMyName[0]=0x27;
  325.     if (gMyOrg[0]>0x27)
  326.         gMyOrg[0]=0x27;
  327.     Mymemcpy(thePrefs.regname, gMyName, gMyName[0]+1);
  328.     Mymemcpy(thePrefs.regorg, gMyOrg, gMyOrg[0]+1);
  329.     thePrefs.maintopic=gMainTopicShowing;
  330.     thePrefs.subtopic=gSubTopicShowing;
  331.     thePrefs.sound=gSoundToggle;
  332.     thePrefs.dup=gAllowDup;
  333.     thePrefs.nonwords=gNonWordsCount;
  334.     thePrefs.animation=gAnimation;
  335.     thePrefs.numletters=gNumLetters;
  336.     thePrefs.unused=0x00;
  337.     thePrefs.lastwipe=gLastWipe;
  338.     thePrefs.fileID=gFileID;
  339. }
  340.  
  341. void CopyPrefsToGlobals(void)
  342. {
  343.     Mymemcpy(gMyName, thePrefs.regname, thePrefs.regname[0]+1);
  344.     Mymemcpy(gMyOrg, thePrefs.regorg, thePrefs.regorg[0]+1);
  345.     gMainTopicShowing=thePrefs.maintopic;
  346.     gSubTopicShowing=thePrefs.subtopic;
  347.     gSoundToggle=thePrefs.sound;
  348.     gAllowDup=thePrefs.dup;
  349.     gNonWordsCount=thePrefs.nonwords;
  350.     gAnimation=thePrefs.animation;
  351.     gNumLetters=thePrefs.numletters;
  352.     if ((gNumLetters<5) || (gNumLetters>6))
  353.         gNumLetters=5;
  354.     gLastWipe=thePrefs.lastwipe;
  355. }
  356.  
  357. void GetRegistration(void)
  358. {
  359.     DialogPtr        theDlog;
  360.     short            itemSelected = 0;
  361.     short            newleft;
  362.     short            newtop;
  363.     short            itemType;
  364.     Handle            item;
  365.     Rect            box;
  366.     
  367.     RemoveHilitePatch();
  368.     
  369.     theDlog = GetNewDialog(131, 0L, (WindowPtr)-1L);
  370.     newleft = qd.screenBits.bounds.left + (((qd.screenBits.bounds.right -
  371.                 qd.screenBits.bounds.left) - (theDlog->portRect.right -
  372.                 theDlog->portRect.left)) / 2);
  373.     newtop = qd.screenBits.bounds.top + (((qd.screenBits.bounds.bottom -
  374.                 qd.screenBits.bounds.top) - (theDlog->portRect.bottom -
  375.                 theDlog->portRect.top)) / 2);
  376.     if(newtop < 15)
  377.         newtop = 15;
  378.     GetDItem(theDlog, 1, &itemType, &item, &box);
  379.     InsetRect(&box, -4, -4);
  380.     SetDItem(theDlog, 8, userItem, (Handle)OutlineDefaultButton, &box);
  381.     ParamText(APPLICATION_NAME, "\p", "\p", "\p");
  382.     
  383.     MoveWindow(theDlog, newleft, newtop, TRUE);
  384.     ShowWindow(theDlog);
  385.     while(itemSelected != 1)
  386.     {
  387.         ModalDialog(0L, &itemSelected);
  388.     }
  389.     GetDItem(theDlog,4,&itemType,&item,&box);
  390.     GetIText(item,gMyName);
  391.     
  392.     GetDItem(theDlog,5,&itemType,&item,&box);
  393.     GetIText(item,gMyOrg);
  394.  
  395.     if (gMyName[0]==0x00)
  396.         DefaultPrefs();
  397.  
  398.     HideWindow(theDlog);
  399.     DisposeDialog(theDlog);
  400.     
  401.     gIsVirgin=TRUE;
  402.     
  403.     InstallHilitePatch();
  404. }
  405.